package io.github.junxworks.qt.modules.stock.service.impl;

import java.util.Date;
import java.util.List;

import org.apache.hc.core5.util.Asserts;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import io.github.junxworks.ep.auth.model.UserModel;
import io.github.junxworks.ep.sys.constants.RecordStatus;
import io.github.junxworks.junx.core.util.NumberUtils;
import io.github.junxworks.qt.modules.stock.dto.SsTradeRecordDto;
import io.github.junxworks.qt.modules.stock.dto.StockTradeCondition;
import io.github.junxworks.qt.modules.stock.entity.SsTradeRecord;
import io.github.junxworks.qt.modules.stock.mapper.TradeMapper;
import io.github.junxworks.qt.modules.stock.service.TradeService;
import io.github.junxworks.qt.modules.stock.vo.SsTradeRecordVo;
import io.github.junxworks.qt.modules.stock.vo.SsTradeStatVo;
import io.github.junxworks.qt.modules.tushare.service.BaseInfoService;

@Service
public class TradeServiceImpl implements TradeService {

	@Autowired
	private TradeMapper tradeMapper;

	@Autowired
	private BaseInfoService profileService;

	@Override
	public List<SsTradeRecordVo> queryTradeList(StockTradeCondition condition) {
		return tradeMapper.queryTradeList(condition);
	}

	@Override
	public SsTradeStatVo statTradeList(StockTradeCondition condition) {
		return tradeMapper.statTradeList(condition);
	}

	@Override
	public int saveBuyRecord(SsTradeRecordDto dto) {
		SsTradeRecord trade = new SsTradeRecord();
		BeanUtils.copyProperties(dto, trade);
		UserModel user = (UserModel) SecurityUtils.getSubject().getPrincipal();
		trade.setCreatorUser(user.getId());
		trade.setCreateTime(new Date());
		trade.setStockName(profileService.getProfileBySymbol(dto.getStockCode()).getName());
		trade.setBuyAmount(NumberUtils.mutiply(trade.getBuyPrice(), trade.getBuyVolume(), 2).doubleValue());
		trade.setStatus(RecordStatus.NORMAL.getValue());
		return tradeMapper.insertWithoutNull(trade);
	}

	@Override
	public SsTradeRecordVo queryTradeDetail(Long id) {
		return tradeMapper.selectByID(id);
	}

	@Override
	@Transactional
	public int saveRecord(SsTradeRecordDto dto) {
		SsTradeRecord trade = new SsTradeRecord();
		BeanUtils.copyProperties(dto, trade);
		if (trade.getSellVolume() != null && trade.getSellVolume() > 0) {
			Asserts.check(trade.getBuyVolume() >= trade.getSellVolume(), "不能超卖");
			//判断是否全卖，是的话就不拆，不是的话就拆
			if (!trade.getBuyVolume().equals(trade.getSellVolume())) {
				//卖部分，拆分之前的买单
				SsTradeRecordDto otrade = new SsTradeRecordDto();
				otrade.setStockCode(trade.getStockCode());
				otrade.setBuyDate(trade.getBuyDate());
				otrade.setBuyPrice(trade.getBuyPrice());
				otrade.setBuyVolume(trade.getBuyVolume() - trade.getSellVolume());
				saveBuyRecord(otrade);
			}
			trade.setStatus((byte) 1);
			trade.setBuyVolume(trade.getSellVolume());
			trade.setBuyAmount(NumberUtils.mutiply(trade.getBuyPrice(), trade.getBuyVolume(), 2).doubleValue());
			trade.setSellAmount(NumberUtils.mutiply(trade.getSellPrice(), trade.getSellVolume(), 2).doubleValue());
			trade.setCostDays((int) ((trade.getSellDate().getTime() - trade.getBuyDate().getTime() + 1000000) / (60 * 60 * 24 * 1000)));
			trade.setProfit(trade.getSellAmount() - trade.getBuyAmount());
			trade.setYieldRate(trade.getProfit() * 100 / trade.getBuyAmount());
			trade.setAnnualizedReturn(trade.getYieldRate() * 365 / trade.getCostDays());
		}
		return tradeMapper.updateWithoutNull(trade);
	}

}
